home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / c / uemlsrc / word.c < prev    next >
C/C++ Source or Header  |  1987-08-24  |  18KB  |  589 lines

  1. /*
  2.  * The routines in this file
  3.  * implement commands that work word at
  4.  * a time. There are all sorts of word mode
  5.  * commands. If I do any sentence and/or paragraph
  6.  * mode commands, they are likely to be put in
  7.  * this file.  Added R.D.R Feb. 1986.
  8.  */
  9. #include        <stdio.h>
  10. #include        <ctype.h>
  11. #include        "ed.h"
  12.  
  13.  
  14. /* Word wrap or fill wrap depending on f flag value.
  15.  * Back-over whatever precedes the point on the current line and
  16.  * stop on the first word-break or the beginning of the line.
  17.  * If we reach the beginning of the line, jump back to the end of the
  18.  * word and start a new line.  Otherwise, break the line at the
  19.  * word-break, eat it, and jump back to the end of the word.
  20.  * Returns TRUE on success, FALSE on errors.
  21.  */
  22. wrapword(f, n)
  23. register int f, n;
  24. {
  25.         int oldp;
  26.         oldp = curwp->w_dotp;
  27.  
  28.         if (! backwword(NULL, 1)) /* punctuation marks */
  29.                 return(FALSE);
  30.         if (oldp != curwp->w_dotp && curwp->w_doto)
  31.                 {
  32.                 if (! backdel(NULL, 1))
  33.                         return(FALSE);
  34.                 if (! newline(TRUE, 1))
  35.                         return(FALSE);
  36.                 }
  37.         if(f)
  38.                 return(forwwword(NULL, 1));
  39.         return(forwwword(NULL, 1) && forwchar(NULL, 1) && backdel(NULL, 1));
  40. }
  41.  
  42. /* FILLPAR Meta command  Fill paragraph to specified fill column and indent
  43.  * column.  Bound to M-Q.
  44.  */
  45.  
  46. fillpar(f, n)
  47. register int f, n;
  48. {
  49.         register int s;
  50.         register short omo;
  51.         register LINE *omp;
  52.  
  53.         if (n > 1)
  54.                 setfillcol(f, n);
  55.  
  56.         if(fillcol == 0)
  57.                 {
  58.                 mlwrite("Fill column not set");
  59.                 (*term.t_beep)();
  60.                 return(FALSE);
  61.                 }
  62.         omp = curwp->w_markp;
  63.         omo = curwp->w_marko;
  64.         curwp->w_markp = curwp->w_dotp;
  65.         curwp->w_marko = curwp->w_doto;
  66.  
  67.         gotbop(FALSE, 1);
  68.         forwchar(FALSE, 1);
  69.         while((n = ltrw(FALSE, 1)) != EOF && n != NULL)
  70.                 forwline(NULL, 1);
  71.         gotbop(FALSE, 1);
  72.         forwchar(FALSE, 1);
  73.         while (TRUE)
  74.                 {
  75.                 if (llength(curwp->w_dotp) == NULL)
  76.                         break;
  77.                 if (curwp->w_dotp == curbp->b_linep)
  78.                         break;
  79.                 if (getccol(FALSE) > fillcol)
  80.                         {
  81.                         if (wrapword(TRUE, NULL) == FALSE)
  82.                                 break;
  83.                         continue;
  84.                         }
  85.                 if (curwp->w_doto ==  llength(curwp->w_dotp)
  86.                         && getccol(FALSE) <= fillcol)
  87.                         {
  88.                         if (forwchar(FALSE, 1) == FALSE)
  89.                                 break;
  90.                         if (curwp->w_dotp == curbp->b_linep)
  91.                                 break;  /* @ EOB */
  92.                         if (llength(curwp->w_dotp) == NULL)
  93.                                 break;  /* @ EOP */
  94.                         if (backchar(FALSE, 1) == FALSE)
  95.                                 break;
  96.                         if (clowsp(FALSE, NULL) == FALSE)
  97.                                 break;
  98.                         continue;
  99.                         }
  100.                 if (forwchar(FALSE, 1) == FALSE)
  101.                         break;
  102.                 }
  103.         curwp->w_dotp = curwp->w_markp;
  104.         curwp->w_doto = curwp->w_marko;
  105.         curwp->w_markp = omp;
  106.         curwp->w_marko = omo;
  107.         curwp->w_flag |= WFHARD;
  108.         curgoal = getccol(FALSE);
  109.         return(TRUE);
  110. }
  111.  
  112. /*
  113.  * PRIVATE VERSION OF INWORD() FOR WRAPWORD(), FORWWORD(), AND BACKWWORD()
  114.  * Return FALSE if the character at dot
  115.  * is a space character or above 0x7e.
  116.  * Otherwise return TRUE.  Any printing
  117.  * character below <DEL> that is not
  118.  * a space character may appear inside a
  119.  * word to be wrapped.  Using a special version
  120.  * of inword() allows us to keep the usual meaning
  121.  * of word for regular movement.
  122.  */
  123. static
  124. inwword()
  125. {
  126.         register int    c;
  127.  
  128.         if (curwp->w_doto == llength(curwp->w_dotp))
  129.                 return (FALSE);
  130.         c = lgetc(curwp->w_dotp, curwp->w_doto);
  131.         if (isspace(c) || c> '~')
  132.                 return (FALSE);
  133.         return (TRUE);
  134. }
  135.  
  136. /*
  137.  * PRIVATE VERSION OF BACKWORD() FOR WRAPWORD() AND FORWWWORD()
  138.  * Move the cursor backward by
  139.  * "n" words. All of the details of motion
  140.  * are performed by the "backchar" and "forwchar"
  141.  * routines. Error if you try to move beyond
  142.  * the buffers.
  143.  */
  144. static
  145. backwword(f, n)
  146. register int f, n;
  147. {
  148.         if (backchar(FALSE, 1) == FALSE)
  149.                 return (FALSE);
  150.         while (inwword() == FALSE)
  151.                 {
  152.                 if (backchar(FALSE, 1) == FALSE)
  153.                         return (FALSE);
  154.                 }
  155.         while (inwword() != FALSE)
  156.                 {
  157.                 if (backchar(FALSE, 1) == FALSE)
  158.                         return (FALSE);
  159.                 }
  160.         return (forwchar(FALSE, 1));
  161. }
  162.  
  163. /* PRIVATE VERSION OF FORWWORD() FOR WRAPWORD() AND BACKWWORD()
  164.  * Move the cursor forward by
  165.  * the specified number of words. All of the
  166.  * motion is done by "forwchar". Error if you
  167.  * try and move beyond the buffer's end.
  168.  */
  169. static
  170. forwwword(f, n)
  171. register int f, n;
  172. {
  173.         while (inwword() == FALSE)
  174.                 {
  175.                 if (forwchar(FALSE, 1) == FALSE)
  176.                         return (FALSE);
  177.                 }
  178.         while (inwword() != FALSE)
  179.                 {
  180.                 if (forwchar(FALSE, 1) == FALSE)
  181.                         return (FALSE);
  182.                 }
  183.         return (TRUE);
  184. }
  185.  
  186. /*
  187.  * Move the cursor forward by
  188.  * the specified number of words. All of the
  189.  * motion is done by "forwchar". Error if you
  190.  * try and move beyond the buffer's end.
  191.  */
  192. forwword(f, n)
  193. register int f, n;
  194. {
  195.         if (n < 0)
  196.                 return (backword(f, -n));
  197.         while (n--) {
  198.                 while (inword() == FALSE) {
  199.                         if (forwchar(FALSE, 1) == FALSE)
  200.                                 return (FALSE);
  201.                 }
  202.                 while (inword() != FALSE) {
  203.                         if (forwchar(FALSE, 1) == FALSE)
  204.                                 return (FALSE);
  205.                 }
  206.         }
  207.         return (TRUE);
  208. }
  209.  
  210. /*
  211.  * Move the cursor backward by
  212.  * "n" words. All of the details of motion
  213.  * are performed by the "backchar" and "forwchar"
  214.  * routines. Error if you try to move beyond
  215.  * the buffers.
  216.  */
  217. backword(f, n)
  218. register int f, n;
  219. {
  220.         if (n < 0)
  221.                 return (forwword(f, -n));
  222.         if (backchar(FALSE, 1) == FALSE)
  223.                 return (FALSE);
  224.         while (n--) {
  225.                 while (inword() == FALSE) {
  226.                         if (backchar(FALSE, 1) == FALSE)
  227.                                 return (FALSE);
  228.                 }
  229.                 while (inword() != FALSE) {
  230.                         if (backchar(FALSE, 1) == FALSE)
  231.                                 return (FALSE);
  232.                 }
  233.         }
  234.         return (forwchar(FALSE, 1));
  235. }
  236.  
  237. /*
  238.  * Move the cursor forward by
  239.  * the specified number of words. As you move,
  240.  * convert any characters to upper case. Error
  241.  * if you try and move beyond the end of the
  242.  * buffer. Bound to "M-U".
  243.  */
  244. upperword(f, n)
  245. register int f, n;
  246. {
  247.         register int    c;
  248.  
  249.         if (n < 0)
  250.                 return (FALSE);
  251.         while (n--) {
  252.                 while (inword() == FALSE) {
  253.                         if (forwchar(FALSE, 1) == FALSE)
  254.                                 return (FALSE);
  255.                 }
  256.                 while (inword() != FALSE) {
  257.                         c = lgetc(curwp->w_dotp, curwp->w_doto);
  258.                         if (islower(c)) {
  259.                                 c = toupper(c);
  260.                                 lputc(curwp->w_dotp, curwp->w_doto, c);
  261.                                 lchange(WFHARD);
  262.                         }
  263.                         if (forwchar(FALSE, 1) == FALSE)
  264.                                 return (FALSE);
  265.                 }
  266.         }
  267.         return (TRUE);
  268. }
  269.  
  270. /*
  271.  * Move the cursor forward by
  272.  * the specified number of words. As you move
  273.  * convert characters to lower case. Error if you
  274.  * try and move over the end of the buffer.
  275.  * Bound to "M-L".
  276.  */
  277. lowerword(f, n)
  278. register int f, n;
  279. {
  280.         register int    c;
  281.  
  282.         if (n < 0)
  283.                 return (FALSE);
  284.         while (n--) {
  285.                 while (inword() == FALSE) {
  286.                         if (forwchar(FALSE, 1) == FALSE)
  287.                                 return (FALSE);
  288.                 }
  289.                 while (inword() != FALSE) {
  290.                         c = lgetc(curwp->w_dotp, curwp->w_doto);
  291.                         if (isupper(c)) {
  292.                                 c = tolower(c);
  293.                                 lputc(curwp->w_dotp, curwp->w_doto, c);
  294.                                 lchange(WFHARD);
  295.                         }
  296.                         if (forwchar(FALSE, 1) == FALSE)
  297.                                 return (FALSE);
  298.                 }
  299.         }
  300.         return (TRUE);
  301. }
  302.  
  303. /*
  304.  * Move the cursor forward by
  305.  * the specified number of words. As you move
  306.  * convert the first character of the word to upper
  307.  * case, and subsequent characters to lower case. Error
  308.  * if you try and move past the end of the buffer.
  309.  * Bound to "M-C".
  310.  */
  311. capword(f, n)
  312. register int f, n;
  313. {
  314.         register int    c;
  315.  
  316.         if (n < 0)
  317.                 return (FALSE);
  318.         while (n--) {
  319.                 while (inword() == FALSE) {
  320.                         if (forwchar(FALSE, 1) == FALSE)
  321.                                 return (FALSE);
  322.                 }
  323.                 if (inword() != FALSE) {
  324.                         c = lgetc(curwp->w_dotp, curwp->w_doto);
  325.                         if (islower(c)) {
  326.                                 c = toupper(c);
  327.                                 lputc(curwp->w_dotp, curwp->w_doto, c);
  328.                                 lchange(WFHARD);
  329.                         }
  330.                         if (forwchar(FALSE, 1) == FALSE)
  331.                                 return (FALSE);
  332.                         while (inword() != FALSE) {
  333.                                 c = lgetc(curwp->w_dotp, curwp->w_doto);
  334.                                 if (isupper(c)) {
  335.                                         c = tolower(c);
  336.                                         lputc(curwp->w_dotp, curwp->w_doto, c);
  337.                                         lchange(WFHARD);
  338.                                 }
  339.                                 if (forwchar(FALSE, 1) == FALSE)
  340.                                         return (FALSE);
  341.                         }
  342.                 }
  343.         }
  344.         return (TRUE);
  345. }
  346.  
  347. /*
  348.  * Kill forward by "n" words.
  349.  * Remember the location of dot. Move forward
  350.  * by the right number of words. Put dot back where
  351.  * it was and issue the kill command for the
  352.  * right number of characters. Bound to "M-D".
  353.  */
  354. delfword(f, n)
  355. register int f, n;
  356. {
  357.         register int    size;
  358.         register LINE   *dotp;
  359.         register int    doto;
  360.  
  361.         if (n < 0)
  362.                 return (FALSE);
  363.         dotp = curwp->w_dotp;
  364.         doto = curwp->w_doto;
  365.         size = 0;
  366.         while (n--) {
  367.                 while (inword() == FALSE) {
  368.                         if (forwchar(FALSE, 1) == FALSE)
  369.                                 return (FALSE);
  370.                         ++size;
  371.                 }
  372.                 while (inword() != FALSE) {
  373.                         if (forwchar(FALSE, 1) == FALSE)
  374.                                 return (FALSE);
  375.                         ++size;
  376.                 }
  377.         }
  378.         curwp->w_dotp = dotp;
  379.         curwp->w_doto = doto;
  380.         return (ldelete(size, TRUE));
  381. }
  382.  
  383. /*
  384.  * Kill backwards by "n" words.
  385.  * Move backwards by the desired number of
  386.  * words, counting the characters. When dot is
  387.  * finally moved to its resting place, fire off
  388.  * the kill command. Bound to "M-Rubout" and
  389.  * to "M-Backspace".
  390.  */
  391. delbword(f, n)
  392. register int f, n;
  393. {
  394.         register int    size;
  395.  
  396.         if (n < 0)
  397.                 return (FALSE);
  398.         if (backchar(FALSE, 1) == FALSE)
  399.                 return (FALSE);
  400.         size = 0;
  401.         while (n--) {
  402.                 while (inword() == FALSE) {
  403.                         if (backchar(FALSE, 1) == FALSE)
  404.                                 return (FALSE);
  405.                         ++size;
  406.                 }
  407.                 while (inword() != FALSE) {
  408.                         if (backchar(FALSE, 1) == FALSE)
  409.                                 return (FALSE);
  410.                         ++size;
  411.                 }
  412.         }
  413.         if (forwchar(FALSE, 1) == FALSE)
  414.                 return (FALSE);
  415.         return (ldelete(size, TRUE));
  416. }
  417.  
  418. /*
  419.  * Return TRUE if the character at dot
  420.  * is a character that is considered to be
  421.  * part of a word. The word character list is hard
  422.  * coded. Should be setable.
  423.  */
  424. inword()
  425. {
  426.         register int    c;
  427.  
  428.         if (curwp->w_doto == llength(curwp->w_dotp))
  429.                 return (FALSE);
  430.         c = lgetc(curwp->w_dotp, curwp->w_doto);
  431.         if (isalnum(c))
  432.                 return (TRUE);
  433.         if (c=='$' || c=='_')   /* For identifiers */
  434.                 return (TRUE);
  435.         return (FALSE);
  436. }
  437.  
  438. /* FTOPUNCT : eXtended Command  Move forward to next punctuation mark.  Bound
  439.  * to CTLX - >.
  440.  */
  441.  
  442. ftopunct(f, n)
  443. register int f, n;
  444. {
  445.         register int c;
  446.  
  447.         do      {
  448.                 if(forwchar(FALSE, 1) == FALSE)
  449.                         return(FALSE);
  450.                 c = lgetc(curwp->w_dotp, curwp->w_doto);
  451.                 }
  452.                 while (! ispunct(c) || isspace(c))
  453.                         ;
  454.         return(TRUE);
  455. }
  456.  
  457. /* BTOPUNCT : eXtended Command  Move backward to last punctuation mark.  Bound
  458.  * to CTLX - <.
  459.  */
  460.  
  461. btopunct(f, n)
  462. register int f, n;
  463. {
  464.         register int c;
  465.  
  466.         do      {
  467.                 if(backchar(FALSE, 1) == FALSE)
  468.                         return(FALSE);
  469.                 c = lgetc(curwp->w_dotp, curwp->w_doto);
  470.                 }
  471.                 while (! ispunct(c) || isspace(c))
  472.                         ;
  473.         return(TRUE);
  474. }
  475.  
  476. /* FORWSENT : Meta Command  Move forward to end punctuation mark.
  477.  * A sentence is defined by a full stop followed by white space.
  478.  * Bound to M-E.
  479.  */
  480.  
  481. forwsent(f, n)
  482. register int f, n;
  483. {
  484.         register int c;
  485.  
  486.         if( n < 0)
  487.                 return(backsent(f, -n));
  488. loop:   while(n--)
  489.         {
  490.                 while(forwchar(FALSE, 1) != FALSE)
  491.                         {
  492.                         c = lgetc(curwp->w_dotp, curwp->w_doto);
  493.                         if(llength(curwp->w_dotp) == NULL)
  494.                                 goto loop;
  495.                         if(c=='.' ||  c=='!' || c=='?')
  496.                                 {
  497.                                 if (forwchar(FALSE, 1) == FALSE)
  498.                                         return(FALSE);
  499.                                 c = lgetc(curwp->w_dotp, curwp->w_doto);
  500.                                 if (c <= ' ' || c == '\"'
  501.                                     || curwp->w_doto == llength(curwp->w_dotp))
  502.                                         goto loop;
  503.                                 }
  504.                         }
  505.                 return(FALSE);  /* EOF or no sentence terminator found */
  506.         }
  507.         return(TRUE);
  508. }
  509.  
  510. /* BACKSENT : Meta Command  Move backward to last terminal punctuation mark.
  511.  * A sentence is defined by a full stop followed by white space.  This
  512.  * function has trouble with some sentences at ends of lines.  Bound to
  513.  * M-A.
  514.  */
  515.  
  516. backsent(f, n)
  517. register int f, n;
  518. {
  519.         register int c;
  520.         register int d;
  521.  
  522.         if (n < 0)
  523.                 return (forwsent(f, -n));
  524.  
  525.         d = 'a';        /* d must begin as an alpha */
  526. loop:   while (n--)
  527.                 {
  528.                 while(backchar(FALSE, 1) != FALSE)
  529.                         {
  530.                         if(llength(curwp->w_dotp) == NULL)
  531.                                 goto loop;
  532.                         c = lgetc(curwp->w_dotp, curwp->w_doto);
  533.                         if(c=='.' ||  c=='?' || c=='!')
  534.                                 if (d <= ' ' || d == '\"'
  535.                                     || curwp->w_doto+1 == llength(curwp->w_dotp)
  536. )
  537.                                         {
  538.                                         forwchar(FALSE, 1);
  539.                                         goto loop;
  540.                                         }
  541.                         d = c;  /* d becomes the last fetched char */
  542.                         }
  543.                 return(FALSE);  /* BOF or no sentence terminator found */
  544.                 }
  545.         return(TRUE);
  546. }
  547.  
  548. /* GOTEOP : META command Goto end of paragraph.  Each paragraph is a
  549.  * block of text bordered by blanklines.  Bound to M-N.
  550.  */
  551.  
  552. goteop(f, n)
  553. register f, n;
  554. {
  555.         if ( n < 0)
  556.                 return(gotbop(f, -n));
  557.         while (n)
  558.                 {
  559.                 if (curwp->w_dotp != curbp->b_linep)
  560.                         forwline(NULL, 1);
  561.                 else
  562.                         return(FALSE);
  563.                 if (llength(curwp->w_dotp) == NULL)
  564.                         --n;
  565.                 }
  566.         return(TRUE);
  567. }
  568.  
  569. /* GOTBOP : META command Goto beginning of paragraph.  Each paragraph is
  570.  * a block of text bordered by blanklines.  Bound to M-P.
  571.  */
  572.  
  573. gotbop(f, n)
  574. register f, n;
  575. {
  576.         if ( n < 0)
  577.                 return(goteop(f, -n));
  578.         while (n)
  579.                 {
  580.                 if (lback(curwp->w_dotp) != curbp->b_linep)
  581.                         backline(NULL, 1);
  582.                 else
  583.                         return(FALSE);
  584.                 if (llength(curwp->w_dotp) == NULL)
  585.                         --n;
  586.                 }
  587.         return(TRUE);
  588. }
  589.